home *** CD-ROM | disk | FTP | other *** search
- /* esort: Sort large files by merging subfiles */
-
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define MAXLINES 1000
- #define MAXSUBFILES 15
-
- struct subfile
- {
- FILE *f;
- char line[BUFSIZ];
- };
-
- int comp(const void *, const void *);
- void make_subfile(char *[], size_t,
- struct subfile *, size_t);
-
- main()
- {
- int i, merge_flag = 0;
- size_t nlines, nfiles = 0, min_idx;
- static char s[BUFSIZ], *lines[MAXLINES];
- static struct subfile subfiles[MAXSUBFILES];
-
- /* Read file - form subfiles if needed */
- for (nlines = 0; fgets(s,BUFSIZ,stdin); ++nlines)
- {
- if (nlines == MAXLINES ||
- (lines[nlines] = malloc(strlen(s)+1)) == NULL)
- {
- /* Sort lines to a temporary merge file */
- merge_flag = 1;
- make_subfile(lines,nlines,subfiles,nfiles++);
- lines[nlines = 0] = malloc(strlen(s)+1);
- assert(lines[0] != NULL);
- }
- strcpy(lines[nlines],s);
- }
-
- if (merge_flag)
- {
- /* Form last merge file from remaining lines */
- make_subfile(lines,nlines,subfiles,nfiles++);
-
- /* Prepare to read temporary files */
- for (i = 0; i < nfiles; ++i)
- {
- FILE *f = subfiles[i].f;
- rewind(f);
- fgets(subfiles[i].line,BUFSIZ,f);
- }
-
- /* Do the merge */
- while (nfiles)
- {
- struct subfile *sfp;
-
- /* Find next output line */
- for (min_idx = 0, i = 1; i < nfiles; ++i)
- if (strcmp(subfiles[i].line,
- subfiles[min_idx].line) < 0)
- min_idx = i;
- sfp = &subfiles[min_idx];
-
- /* Output the line */
- fputs(sfp->line,stdout);
- fflush(stdout);
- assert(!ferror(stdout));
-
- /* Get the next line from this file */
- if (fgets(sfp->line,BUFSIZ,sfp->f) == NULL)
- subfiles[min_idx] = subfiles[--nfiles];
- }
- }
- else
- {
- /* Sort singleton file */
- qsort(lines,nlines,sizeof lines[0],comp);
- for (i = 0; i < nlines; ++i)
- {
- fputs(lines[i],stdout);
- fflush(stdout);
- assert(!ferror(stdout));
- }
- }
-
- return 0;
- }
-
- int comp(const void *p1, const void *p2)
- {
- return strcmp(* (char **) p1, * (char **) p2);
- }
-
- void make_subfile(char *lines[],size_t nl,
- struct subfile subf[],size_t nf)
- {
- int i;
- FILE *f = tmpfile();
- assert(f);
-
- /* Write sorted subfile to temporary file */
- qsort(lines,nl,sizeof lines[0],comp);
- for (i = 0; i < nl; ++i)
- {
- fputs(lines[i],f);
- fflush(f);
- assert(!ferror(f));
- free(lines[i]);
- }
- subf[nf].f = f;
- }
-
-